package com.pxmeta.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.pxmeta.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
public class HttpUtils {


    public static JSONObject doPost(String url, JSONObject body, HttpHeaders headers) {
        RestTemplate restTemplate = new RestTemplate();
        org.springframework.http.HttpEntity<Object> entity = new org.springframework.http.HttpEntity<>(body, headers);
        return restTemplate.postForObject(url, entity, JSONObject.class);
    }

    public static JSONObject doPost(String url, Map<String, Object> body) {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.postForObject(url, body, JSONObject.class);
    }

    public static JSONObject doPostForm(String url, Map<String, String> form) {
        RestTemplate restTemplate = new RestTemplate();
        MultiValueMap<String, String> mulmap = new LinkedMultiValueMap<>();
        mulmap.setAll(form);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        ResponseEntity<String> result = null;
        org.springframework.http.HttpEntity<MultiValueMap<String, String>> request = new org.springframework.http.HttpEntity<>(mulmap, headers);
        //执行HTTP请求
        result = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
        return JSONObject.parseObject(result.getBody());
    }


    public static JSONObject doGet(String url, Map<String, String> params, Map<String, String> headers) {
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            Set<Map.Entry<String, String>> entries = params.entrySet();
            ArrayList<NameValuePair> pairs = new ArrayList<>();
            for (Map.Entry<String, String> entry : entries) {
                String key = entry.getKey();
                String value = entry.getValue();
                pairs.add(new BasicNameValuePair(key, value));
            }
            uriBuilder.addParameters(pairs);
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            RequestConfig requestConfig = RequestConfig.custom()
                    .setCookieSpec(CookieSpecs.STANDARD)
                    .setConnectionRequestTimeout(60000)
                    .setSocketTimeout(60000)
                    .setConnectTimeout(60000).build();
            httpGet.setConfig(requestConfig);
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                String value = entry.getValue();
                String key = entry.getKey();
                httpGet.setHeader(key, value);
            }
            response = client.execute(httpGet);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                throw new ServiceException("第三方接口异常！");
            }
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            return JSONObject.parseObject(result);
        } catch (Exception e) {
            throw new ServiceException("接口调用失败！");
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                client.close();
            } catch (IOException e) {
                log.error("调用失败,错误信息：{}", e.getMessage());
            }
        }
    }


    public static JSONObject doGet(String url, Map<String, String> headers) {
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            RequestConfig requestConfig = RequestConfig.custom()
                    .setCookieSpec(CookieSpecs.STANDARD)
                    .setConnectionRequestTimeout(60000)
                    .setSocketTimeout(60000)
                    .setConnectTimeout(60000).build();
            httpGet.setConfig(requestConfig);
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                String value = entry.getValue();
                String key = entry.getKey();
                httpGet.setHeader(key, value);
            }
            response = client.execute(httpGet);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                throw new ServiceException("第三方接口异常！");
            }
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            return JSONObject.parseObject(result);
        } catch (Exception e) {
            throw new ServiceException("接口调用失败！");
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                client.close();
            } catch (IOException e) {
                log.error("调用失败,错误信息：{}", e.getMessage());
            }
        }
    }

}
